package va_btree;

import btree.*;
import bufmgr.HashEntryNotFoundException;
import bufmgr.InvalidFrameNumberException;
import bufmgr.PageNotReadException;
import bufmgr.PageUnpinnedException;
import bufmgr.ReplacerException;
import global.AttrType;
import global.IndexType;
import global.RID;
import heap.*;
import index.IndexException;
import iterator.CondExpr;
import iterator.FileScanException;
import iterator.FldSpec;
import iterator.InvalidRelation;
import iterator.JoinsException;
import iterator.PredEvalException;
import iterator.SortException;
import iterator.TupleUtilsException;
import iterator.UnknowAttrType;
import iterator.WrongPermat;
import va.BaseIndexScan;
import va.VAEntry;

import java.io.IOException;

public class VABTIndexScan extends BaseIndexScan {

    public VABTreeScan scanner;
    public int noOfBits;

    public VABTIndexScan(IndexType index,
                         String relName,
                         String indexName,
                         AttrType[] types,
                         short[] str_sizes,
                         int noInFields,
                         int noOutFields,
                         FldSpec[] outFields,
                         CondExpr[] selects,
                         int fldNum,
                         int noOfBits) throws IndexException, HFException, HFBufMgrException, HFDiskMgrException, IOException, InvalidTupleSizeException, ConstructPageException, GetFileEntryException, AddFileEntryException, PinPageException, IteratorException, KeyNotMatchException, UnpinPageException, InvalidTypeException, FileScanException, TupleUtilsException, InvalidRelation, JoinsException, PageNotReadException, PredEvalException, UnknowAttrType, FieldNumberOutOfBoundException, WrongPermat {
        super(index, relName, indexName, types, str_sizes, noInFields, noOutFields, outFields, selects, fldNum);
        VABTreeFile file = new VABTreeFile(indexName, noOfBits);
        this.scanner = new VABTreeScan(file);

        this.noOfBits = noOfBits;
        String lowKey = "";
        String highKey = "";
        for (int i = 0; i < 100; i++) {
            // Just set the low and high key to the highest and lowest possible
            for (int j = 0; j < noOfBits; j++) {
                lowKey += "0";
                highKey += "1";
            }
        }
        this.scanner.btScan = this.scanner.file.new_scan(new StringKey(lowKey), new StringKey(highKey));
    }

    @Override
    public Tuple get_next() throws Exception {
        VAEntry entry = this.scanner.getNextBTreeVA(this.noOfBits);
        if (entry == null) {
            return null;
        }
        
        
        RID rid = entry.rid;
        Tuple tuple = getRecordDirect(rid);
        return this.formatTuple(tuple);
    }
    
    //Return VA entry
    public VAEntry get_next_entry() throws Exception {
        VAEntry entry = this.scanner.getNextBTreeVA(this.noOfBits);
        if (entry == null) {
            return null;
        }
        return entry;
 
    }

    // Closes the scanner to avoid pinned buffer pages
    @Override
    public void close() throws IOException, JoinsException, SortException,
            IndexException, PageUnpinnedException, InvalidFrameNumberException, HashEntryNotFoundException, ReplacerException {
        super.close();
        this.scanner.close();
    }
}
